/**
 * @author luguoxiang
 * @date 2022/7/5
 * 开源项目：https://gitee.com/lgx1992/lg-soar 求star！请给我star！请帮我点个star！
 */
import { Select } from 'tdesign-vue-next';
import {
  deepCopy,
  formatStr,
  IConfigSchema,
  IFormSchema,
  LgDict,
  LgDictProps,
  LgSwitch,
  LgUpload,
  LgUploadProps,
  toOptions,
} from '@/soar';
import { datetimeFmt, dateFmt, timeFmt } from '@/config/global';

/**
 * 生成表单配置
 * @param {Config}config 配置
 * @returns {IFormSchema}
 */
export function toForm(config: IFormSchema<unknown> | IConfigSchema<unknown>): object {
  let form;
  // @ts-ignore
  if (config.form) {
    // @ts-ignore
    form = config.form;
    form.params ??= config.params;
    form = deepCopy(form, true);
    // 基本字段复制
    form.field ??= config.field;
    form.label ??= config.label;
    form.dataType ??= config.dataType;
    form.predicate ??= config.predicate;
  } else {
    form = deepCopy(config, true);
    delete form.detail;
    delete form.search;
    delete form.table;
  }
  delete form.order;

  // 插槽处理
  if (typeof form.slots === 'string') {
    form.slots = { default: form.slots };
  } else {
    form.slots ??= {};
  }

  if (!form.slots.default && !form.component) {
    // 根据类型自动配置组件
    switch (form.dataType) {
      case 'number':
        form.component = 't-input-number';
        break;
      case 'dict':
        form.component = LgDict;
        break;
      case 'datetime':
        form.component = 't-date-picker';
        break;
      case 'date':
        form.component = 't-date-picker';
        break;
      case 'time':
        form.component = 't-time-picker';
        break;
      case 'enum':
        form.component = Select;
        break;
      case 'boolean':
        form.component = LgSwitch;
        break;
      case 'img':
        form.component = LgUpload;
        break;
      case 'file':
        form.component = LgUpload;
        break;
      default:
        form.component = 't-input';
        break;
    }
  }

  // 根据类型自动配置参数
  if (!form.params) {
    switch (form.dataType) {
      case 'datetime':
        form.params = datetimeFmt;
        break;
      case 'date':
        form.params = dateFmt;
        break;
      case 'time':
        form.params = timeFmt;
        break;
      case 'img':
        form.params = 'urlList';
        break;
      default:
        break;
    }
  }

  if (typeof form.componentProps !== 'function') {
    // 根据类型自动配置组件
    switch (form.dataType) {
      case 'number':
        form.componentProps = { placeholder: '请输入${label}', theme: 'column', ...form.componentProps };
        break;
      case 'dict':
        form.componentProps = {
          code: form.params,
          placeholder: '请选择${label}',
          ...form.componentProps,
        } as LgDictProps;
        break;
      case 'datetime':
        form.componentProps = {
          format: form.params,
          valueType: form.params,
          allowInput: true,
          enableTimePicker: true,
          placeholder: '请选择${label}',
          ...form.componentProps,
        };
        break;
      case 'date':
        form.componentProps = {
          format: form.params,
          valueType: form.params,
          allowInput: true,
          placeholder: '请选择${label}',
          ...form.componentProps,
        };
        break;
      case 'time':
        form.componentProps = {
          format: form.params,
          allowInput: true,
          placeholder: '请选择${label}',
          ...form.componentProps,
        };
        break;
      case 'enum':
        form.componentProps = {
          options: toOptions(form.params),
          placeholder: '请选择${label}',
          ...form.componentProps,
        };
        break;
      case 'boolean':
        if (form.params) {
          const options = toOptions(form.params);
          form.componentProps = {
            customValue: [options[0].value, options[1].value],
            label: [options[0].label, options[1].label],
            ...form.componentProps,
          };
        }
        break;
      case 'img':
        form.componentProps = {
          valueType: form.params,
          accept: 'image/*',
          type: 'img',
          ...form.componentProps,
        } as LgUploadProps;
        break;
      case 'file':
        form.componentProps = {
          valueType: form.params,
          ...form.componentProps,
        } as LgUploadProps;
        break;
      default:
        form.componentProps = { placeholder: '请输入${label}', ...form.componentProps };
        break;
    }
  }

  // formItem 初始化
  form.formItemProps ??= {};
  form.formItemProps.name ??= form.field;
  if (!form.slots.label) {
    form.formItemProps.label ??= form.label;
  }

  // 校验规则处理
  if (form.rules) {
    if (typeof form.rules === 'boolean') {
      form.rules = [{ required: form.rules, message: `${form.formItemProps.label}必填`, trigger: 'blur' }];
    } else if (typeof form.rules === 'string') {
      form.rules = [{ required: true, message: form.rules, trigger: 'blur' }];
    }
  }

  // 组件配置处理
  form.componentProps ??= {};
  if (typeof form.componentProps.placeholder === 'string') {
    form.componentProps.placeholder = formatStr(form.componentProps.placeholder, form);
  } else if (Array.isArray(form.componentProps.placeholder)) {
    form.componentProps.placeholder = form.componentProps.placeholder.map((x) => formatStr(x, form));
  }

  return form;
}

/**
 * 获取表单配置
 * @param fieldList
 */
export function getForms(fieldList: Array<IFormSchema<unknown> | IConfigSchema<unknown>>): object[] {
  return (
    fieldList
      // 过滤
      .filter((x: any) => x.form !== false)
      // 排序
      .sort((a: any, b: any) => {
        if (a.form) {
          a = a.form;
        }
        if (b.form) {
          b = b.form;
        }
        return (a.order ?? 0) - (b.order ?? 0);
      })
      // 解析
      .map(toForm)
      .filter((x: any) => x.predicate?.() !== false)
  );
}
